﻿/*
AwpAdmin, an admin tool for Battlefield 3
Copyright (C) 2011 agentwite, Timi, Unseen, AlCapwn

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

You can contact us at http://bf3admin.codeplex.com/.
*/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Lifetime;
using System.Net.Battlefield3;

namespace AwpAdminTool
{
    /// <summary>
    /// The abstract class that all <see cref="Plugin">Plugins</see> inherit from.
    /// </summary>
    public abstract class Plugin
        : MarshalByRefObject
    {
        #region Base Plugin Members
        AwpAdmin _ParentAdmin;
        /// <summary>
        /// Gets the parent <see cref="AwpAdmin"/> of the <see cref="Plugin"/>.
        /// </summary>
        /// <value>The parent <see cref="AwpAdmin"/>.</value>
        public AwpAdmin ParentAdmin { get { return _ParentAdmin; } }

        internal AppDomain PluginAppDomain { get { return AppDomain.CurrentDomain; } } //may have to change to public. idk.

        /// <summary>
        /// Initializes the lifetime lease of the <see cref="Plugin"/>.
        /// </summary>
        /// <returns>An initialized ILease that allows you to control the lifetime of the <see cref="Plugin"/>.</returns>
        public sealed override object InitializeLifetimeService() //sealed because this is important
        {
            ILease lease = base.InitializeLifetimeService() as ILease;
            if (lease.CurrentState == LeaseState.Initial)
                lease.InitialLeaseTime = TimeSpan.Zero;
            return lease;
        }

        ///// <summary>
        ///// Unloads the plugin.
        ///// </summary>
        //public void Unload()
        //{
        //    AppDomain.Unload(PluginAppDomain);
        //}
        #endregion

        //events are done as virtual methods because regular events cause the assembly to load into ui appdomain
        //with virtual methods, plugins can choose what events are in their code
        #region RCON Events
        /// <summary>
        /// Occurs when the <see cref="RconClient"/> receives a <see cref="Packet"/>
        /// </summary>
        /// <param name="e">A <see cref="RawReadEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnRawRead(RawReadEventArgs e){}

        /// <summary>
        /// Occurs when the server responds to the <see cref="RconClient"/>.
        /// </summary>
        /// <param name="e">A <see cref="ResponseEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnResponse(ResponseEventArgs e){}

        /// <summary>
        /// Occurs when the <see cref="RconClient"/> has connected to the server.
        /// </summary>
        protected internal virtual void OnConnected(){}

        /// <summary>
        /// Occurs when the <see cref="RconClient"/> has encountered an error when trying to connect to the server.
        /// </summary>
        /// <remarks>
        /// This will only be raised when a SocketException occurs in the asynchronous connect method.
        /// </remarks>
        /// <param name="e">A <see cref="ConnectErrorEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnConnectError(ConnectErrorEventArgs e){}

        /// <summary>
        /// Occurs when the <see cref="RconClient"/> has disconnected from the server.
        /// </summary>
        /// <param name="e">A <see cref="DisconnectedEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnDisconnected(DisconnectedEventArgs e) { }

        /// <summary>
        /// Occurs when the <see cref="RconClient"/> logs into the server.
        /// </summary>
        /// <remarks>The <see cref="RconClient"/> will have limited communication ability while not logged in.</remarks>
        protected internal virtual void OnLoggedOn(){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> leaves the server.
        /// </summary>
        /// <param name="e">A <see cref="PlayerEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerLeft(PlayerEventArgs e){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> joins the server.
        /// </summary>
        /// <param name="e">A <see cref="PlayerEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerJoined(PlayerEventArgs e){}

        /// <summary>
        /// Occurs when a player is joining the server.
        /// </summary>
        /// <param name="e">A <see cref="PlayerJoiningEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerJoining(PlayerJoiningEventArgs e){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> is authenticated.
        /// </summary>
        /// <param name="e">A <see cref="PlayerAuthenticatedEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerAuthenticated(PlayerAuthenticatedEventArgs e){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> is killed.
        /// </summary>
        /// <param name="e">A <see cref="PlayerKilledEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerKilled(PlayerKilledEventArgs e){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> spawns.
        /// </summary>
        /// <param name="e">A <see cref="PlayerEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerSpawned(PlayerEventArgs e){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> is moved to a new team, squad, or both.
        /// </summary>
        /// <param name="e">A <see cref="PlayerMovedEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerMoved(PlayerEventArgs e) { }

        /// <summary>
        /// Occurs when the round has ended.
        /// </summary>
        protected internal virtual void OnRoundOver(){}

        /// <summary>
        /// Occurs when a level has been loaded.
        /// </summary>
        /// <param name="e">A <see cref="LevelLoadedEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnLevelLoaded(LevelLoadedEventArgs e){}

        /// <summary>
        /// Occurs when a <see cref="Player"/> or the server sends a message.
        /// </summary>
        /// <param name="e">A <see cref="PlayerChatEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPlayerChat(PlayerChatEventArgs e){}

        /// <summary>
        /// Occurs when PunkBuster sends a message.
        /// </summary>
        /// <param name="e">A <see cref="PunkBusterMessageEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnPunkBusterMessage(PunkBusterMessageEventArgs e){}
        #endregion

        #region AwpAdmin Events
        /// <summary>
        /// Occurs when the <see cref="AwpAdmin"/> receives a command.
        /// </summary>
        /// <param name="e">A <see cref="CommandEventArgs"/> that contains the event data.</param>
        protected internal virtual void OnCommand(CommandEventArgs e){}
        #endregion

        /// <summary>
        /// Implements a new <see cref="Plugin"/> of the specified <see cref="AwpAdmin"/>.
        /// </summary>
        /// <param name="awpAdmin">The parent <see cref="AwpAdmin"/>.</param>
        protected Plugin(AwpAdmin awpAdmin)
        {
            _ParentAdmin = awpAdmin;
        }
    }
}
